package com.ibeetl.admin.core.web;

import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreRole;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.rbac.UserLoginInfo;
import com.ibeetl.admin.core.rbac.tree.MenuItem;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.service.MessageService;
import com.ibeetl.admin.core.service.TodoService;
import com.ibeetl.admin.core.util.Captcha;
import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.MD5Coder;
import com.ibeetl.admin.core.util.SessionListener;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;

@Controller
public class IndexController {

    private final Log log = LogFactory.getLog(this.getClass());

    @Autowired
    CorePlatformService platformService;


    @Autowired
    CoreUserService userService;

    @Autowired
    HttpRequestLocal httpRequestLocal;

    @Autowired
    MessageService messageService;

    @Autowired
    TodoService todoService;

    @Autowired
    private Environment  environment;


    @RequestMapping("/")
    public ModelAndView login() {
        ModelAndView view = new ModelAndView("/login_final.html");
        return view;
    }

    /**
     * 生成验证码图片的请求
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/captcha")
    @ResponseBody
    public String imageCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");

        OutputStream os = response.getOutputStream();
        //返回验证码和图片的map
        Map<String, Object> map = Captcha.getImageCode(86, 37, os);
        String simpleCaptcha = "simpleCaptcha";

        /**
         * 在session记录二维码的值和生成时间
         */
        request.getSession().setAttribute(simpleCaptcha, map.get("strEnsure").toString().toLowerCase());
        request.getSession().setAttribute("codeTime",System.currentTimeMillis());
        try {
            /**
             * 向响应流写入图片数据
             */
            ImageIO.write((BufferedImage) map.get("image"), "jpg", os);
        } catch (IOException e) {
            return "";
        } finally {
            if (os != null) {
                os.flush();
                os.close();
            }
        }
        return null;
    }

    @RequestMapping("/login.do")
    public ModelAndView login(HttpServletRequest request, HttpSession session, String checkCode, String code, String password, Model model) throws UnsupportedEncodingException {
        code = StringEscapeUtils.escapeHtml4(code);
        //password = StringEscapeUtils.escapeHtml4(password);
        Base64.Decoder decoder = Base64.getDecoder();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(password)){
            password = new String(decoder.decode(password), StandardCharsets.UTF_8);
        }
        //System.out.println("password:"+password);
        String username = request.getParameter("username");
        String loginType = request.getParameter("loginType");
        String dateData = request.getParameter("dateData");
        String checkData = request.getParameter("checkData");
        log.info("session["+session.getId()+"]");
        log.info("username="+username+",loginType="+loginType+",dateData="+dateData+",checkData="+checkData);
        try {
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(username)){

                /* 登录时间校验 */
                Date thisDate = new Date();
                //设置日期格式
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm");
                //对方系统时间
                Date reqDate = df.parse(dateData);
                //过期时间 - 配置文件取
                int ignoreTime = environment.getProperty("login.outTime",Integer.class);

                long itervalTime1 = thisDate.getTime() - reqDate.getTime();
                long itervalTime2 = reqDate.getTime() - thisDate.getTime();
                if(itervalTime1 > ignoreTime * 60 * 1000 || itervalTime2 > ignoreTime * 60 * 1000){
                    request.setAttribute("errorMsg", "登录超时,有效时间为10分钟！");
                    model.addAttribute("errorMessage", "登录超时,有效时间为10分钟！");
                    ModelAndView view = new ModelAndView("redirect:/");
                    return view;
                }

                 /* 加密信息校验 */
                //MD5加密key - 配置文件取
                String loginKey = environment.getProperty("login.key");
                String reqParamMd5Str = MD5Coder.getMD5Char(MD5Coder.getMD5Char(loginKey)+username+dateData);
                if(!checkData.equals(reqParamMd5Str)){
                    request.setAttribute("errorMsg", "登录失败,非法请求信息！");
                    model.addAttribute("errorMessage", "登录失败,非法请求信息！");
                    ModelAndView view = new ModelAndView("redirect:/");
                    return view;
                }
                UserLoginInfo info = new UserLoginInfo();
                if(!"1".equals(loginType)){
                    info = userService.login(username, "","1");
                }
                if(null != info){
                    /**
                     * 登录成功后的处理
                     */
                    CoreUser user = info.getUser();
                    //保存登陆信息到sessionMap
//                    saveLoginInfoSessionMap(session, user);

                    CoreOrg currentOrg = info.getOrgs().get(0);
                    for (CoreOrg org : info.getOrgs()) {
                        if (org.getId().equals(user.getOrgId())) {
                            currentOrg = org;
                            break;
                        }
                    }

                    info.setCurrentOrg(currentOrg);
                    // 记录登录信息到session
                    this.platformService.setLoginUser(info.getUser(), info.getCurrentOrg(), info.getOrgs());
                    //完成登录 进入首页
                    ModelAndView view = new ModelAndView("redirect:/index.do");
                    return view;
                }else{
                    model.addAttribute("username", username);
                    model.addAttribute("dateData", dateData);
                    model.addAttribute("checkData", checkData);
                    model.addAttribute("loginType", 1);
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
            request.setAttribute("errorMsg", "系统处理异常！");
            model.addAttribute("errorMessage", "系统处理异常");
            ModelAndView view = new ModelAndView("redirect:/");
            return view;
        }

        // 获得验证码对象
        Object cko = session.getAttribute("simpleCaptcha");
        if (cko == null) {

            request.setAttribute("errorMsg", "请输入验证码！");
            model.addAttribute("errorMessage", "请输入验证码");
            ModelAndView view = new ModelAndView("/");
            return view;
        }
        String captcha = cko.toString();
        // 验证码有效时长为1分钟
        Date now = new Date();
        Long codeTime = Long.valueOf(session.getAttribute("codeTime") + "");
        // 判断验证码输入是否正确
        if (StringUtils.isEmpty(checkCode) || captcha == null || !(checkCode.equalsIgnoreCase(captcha))) {
            request.setAttribute("errorMsg", "验证码错误！");
            model.addAttribute("errorMessage", "验证码错误！");

            ModelAndView view = new ModelAndView("/");
            return view;
        } else if ((now.getTime() - codeTime) / 1000 / 60 > 5) {
            request.setAttribute("errorMsg", "验证码已失效，请重新输入！");
            model.addAttribute("errorMessage", "验证码已失效，请重新输入！");

            ModelAndView view = new ModelAndView("/");
            return view;
        } else {
            // 在这里可以处理自己需要的事务，比如验证登陆等
            UserLoginInfo info = null;
            try {
                info = userService.login(code, password,"0");
                /**
                 * 登录成功后的处理
                 */
                CoreUser user = info.getUser();
                //保存登陆信息到sessionMap
//                saveLoginInfoSessionMap(session, user);
                if(!StringUtils.isEmpty(username)){
                    user.setForeignName(username);
                    userService.update(user);
                }
            } catch (Exception e) {
                model.addAttribute("errorMessage", e.getMessage());

                ModelAndView view = new ModelAndView("/");
                return view;
            }
            if (info == null) {
                model.addAttribute("errorMessage", "用户名密码错误!");

                ModelAndView view = new ModelAndView("/");
                return view;
            }
            CoreUser user = info.getUser();
            CoreOrg currentOrg = info.getOrgs().get(0);
            for (CoreOrg org : info.getOrgs()) {
                if (org.getId().equals(user.getOrgId())) {
                    currentOrg = org;
                    break;
                }
            }

            info.setCurrentOrg(currentOrg);
            // 记录登录信息到session
            this.platformService.setLoginUser(info.getUser(), info.getCurrentOrg(), info.getOrgs());
            ModelAndView view = new ModelAndView("redirect:/index.do");
            return view;
        }
    }

    /**
     * 记录当前登陆用户
     * @param session
     * @param user
     */
    private void saveLoginInfoSessionMap(HttpSession session, CoreUser user) {
        String sessionId = session.getId();
        /**
         * 如果该用户已登录
         */
        if(SessionListener.LOGIN_USER_MAP.containsKey(user.getId())){
            if(!sessionId.equalsIgnoreCase(SessionListener.LOGIN_USER_MAP.get(user.getId()))){
                /**
                 * 将旧用户加入下线集合
                 */
                SessionListener.LOGOUT_USER_MAP.put(SessionListener.LOGIN_USER_MAP.get(user.getId()), user.getId());
                SessionListener.LOGIN_USER_MAP.put(user.getId(), sessionId);
            }
        }else {
            /**
             * 首次登录加入登录集合中
             */
            SessionListener.LOGIN_USER_MAP.put(user.getId(), sessionId);
        }
    }

    @RequestMapping("/index.do")
    public ModelAndView index() {
        ModelAndView view = new ModelAndView("/index.html");
        CoreUser currentUser = null;
        try {
            currentUser = platformService.getCurrentUser();
        } catch (Exception e) {
            return new ModelAndView("redirect:/login.do");
        }
        Long orgId = platformService.getCurrentOrgId();
        MenuItem menuItem = platformService.getMenuItem(currentUser.getId(), orgId);
        view.addObject("menus", menuItem);

        String needInfo = currentUser.getNeedInfo();
        CoreRole role = platformService.getRole();
        if ("1".equalsIgnoreCase(needInfo)) {

            /**
             * 企业
             */
            if (role.getId() == CoreUser.COMPANY) {
                view.addObject("needInit", "1");
            }
            /**
             * 个人
             */
            else if (role.getId() == CoreUser.PERSON) {
                view.addObject("needInit", "2");
            }
        } else if ("2".equalsIgnoreCase(needInfo)){
            //初次登录填写完基本信息后 强制弹框需修改密码
            view.addObject("needInit", "3");
        } else {
            view.addObject("needInit", "0");
        }
        int newMessageCount = messageService.countNotReadMessage(currentUser, role);
        int todoCount = todoService.todoConut();
        view.addObject("isPerson", role.getId() == 177);
        view.addObject("newMessageCount", newMessageCount);
        view.addObject("todoCount", todoCount);

        return view;
    }

    @RequestMapping("/logout.do")
    public ModelAndView logout(HttpServletRequest request, String message, RedirectAttributes attributes) {
        HttpSession session = request.getSession();
        String sessionId = session.getId();
        SessionListener.LOGOUT_USER_MAP.remove(sessionId);
        Enumeration eum = session.getAttributeNames();
        while (eum.hasMoreElements()) {
            String key = (String) eum.nextElement();
            session.removeAttribute(key);
        }

        if("1".equalsIgnoreCase(message)){
            attributes.addFlashAttribute("errorMessage", "账号在其他地方登录");
        }
        ModelAndView view = new ModelAndView("redirect:/");
        return view;
    }

    @RequestMapping("/changeOrg.do")
    public ModelAndView changeOrg(HttpServletRequest request, Long orgId) {
        platformService.changeOrg(orgId);
        ModelAndView view = new ModelAndView("redirect:/index.do");
        return view;
    }

}
